import java.awt.Frame;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

import lejos.pc.comm.NXTComm;
import lejos.pc.comm.NXTCommException;
import lejos.pc.comm.NXTCommFactory;
import lejos.pc.comm.NXTInfo;
import controle.Fuzzy;


/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class MainWindowComandaNXT extends javax.swing.JFrame 
{
	static private NXTComm nxtComm;
	//Criando streams de dados para o NXT
	InputStream is;
	OutputStream os;
	
	//Criando streams de dados gen�ricos
	DataOutputStream dos;
	DataInputStream dis;
	
	boolean conectou;
	
	// Variaveis da simula��o
	private int anguloAtual;
	private double xAtual;
	private double yAtual;
	private double delta = 5;
	private int velocidadePadrao = 200;
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	{
		//Set Look & Feel
		try {
			javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
		} catch(Exception e) {
			e.printStackTrace();
		}
	}

	
	private JButton jBtnSair;
	private JButton jBtnVelocidade;
	private JButton jBtnVoltar;
	private JButton jBtnConectar;
	private JButton jBtnParar;
	private JButton jBtnVirarD;
	private JButton jBtnVirarE;
	private JButton jBtnGirarD;
	private JButton jBtnGirarE;
	private JButton jBtnAndar;
	private JButton jBtnMedir;
	private JTextField jTxt;
	private JLabel jOut;

	/**
	* Auto-generated main method to display this JFrame
	*/
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				MainWindowComandaNXT inst = new MainWindowComandaNXT();
				inst.setLocationRelativeTo(null);
				inst.setVisible(true);
			}
		});
	}
	
	public MainWindowComandaNXT() {
		super();
		initGUI();
	}
	
	private void initGUI() {
		try {
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			getContentPane().setLayout(null);
			this.setExtendedState(Frame.MAXIMIZED_BOTH);
			{
				jBtnSair = new JButton();
				getContentPane().add(jBtnSair);
				jBtnSair.setText("Sair");
				jBtnSair.setBounds(0, 633, 305, 36);
				jBtnSair.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent evt) {
						jBtnSairMouseClicked(evt);
					}
				});
			}
			{
				jTxt = new JTextField();
				getContentPane().add(jTxt);
				jTxt.setBounds(0, 0, 152, 27);
			}
			{
				jOut = new JLabel();
				getContentPane().add(jOut);
				jOut.setBounds(153, 0, 152,27);
				jOut.setText("Distancia");
			}
			{
				jBtnVelocidade = new JButton();
				getContentPane().add(jBtnVelocidade);
				jBtnVelocidade.setText("Velocidade");
				jBtnVelocidade.setBounds(0, 89, 305, 36);
				jBtnVelocidade.setEnabled(false);
				jBtnVelocidade.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent evt) {
						jBtnVelocidadeMouseClicked(evt);
					}
				});
			}
			{
				jBtnAndar = new JButton();
				getContentPane().add(jBtnAndar);
				jBtnAndar.setText("Andar");
				jBtnAndar.setBounds(0, 149, 305, 36);
				jBtnAndar.setEnabled(false);
				jBtnAndar.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent evt) {
						jBtnAndarMouseClicked(evt);
					}
				});
			}
			{
				jBtnVoltar = new JButton();
				getContentPane().add(jBtnVoltar);
				jBtnVoltar.setText("Voltar");
				jBtnVoltar.setBounds(0, 210, 305, 36);
				jBtnVoltar.setEnabled(false);
				jBtnVoltar.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent evt) {
						jBtnVoltarMouseClicked(evt);
					}
				});
			}
			{
				jBtnGirarE = new JButton();
				getContentPane().add(jBtnGirarE);
				jBtnGirarE.setText("Girar Esquerda");
				jBtnGirarE.setBounds(0, 270, 305, 36);
				jBtnGirarE.setEnabled(false);
				jBtnGirarE.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent evt) {
						jBtnGirarEMouseClicked(evt);
					}
				});
			}
			{
				jBtnGirarD = new JButton();
				getContentPane().add(jBtnGirarD);
				jBtnGirarD.setText("Girar Direita");
				jBtnGirarD.setBounds(0, 330, 305, 36);
				jBtnGirarD.setEnabled(false);
				jBtnGirarD.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent evt) {
						jBtnGirarDMouseClicked(evt);
					}
				});
			}
			{
				jBtnVirarE = new JButton();
				getContentPane().add(jBtnVirarE);
				jBtnVirarE.setText("Virar Esquerda");
				jBtnVirarE.setBounds(0, 391, 305, 36);
				jBtnVirarE.setEnabled(false);
				jBtnVirarE.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent evt) {
						if(!jBtnVirarE.isEnabled())
						{
							return;
						}
						jBtnVirarEMouseClicked(evt);
					}
				});
			}
			{
				jBtnVirarD = new JButton();
				getContentPane().add(jBtnVirarD);
				jBtnVirarD.setText("Virar Direita");
				jBtnVirarD.setBounds(0, 451, 305, 36);
				jBtnVirarD.setEnabled(false);
				jBtnVirarD.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent evt) {
						jBtnVirarDMouseClicked(evt);
					}
				});
			}
			{
				jBtnParar = new JButton();
				getContentPane().add(jBtnParar);
				jBtnParar.setText("Parar");
				jBtnParar.setBounds(0, 511, 305, 36);
				jBtnParar.setEnabled(false);
				jBtnParar.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent evt) {
						jBtnPararMouseClicked(evt);
					}
				});
			}
			{
				jBtnConectar = new JButton();
				getContentPane().add(jBtnConectar);
				jBtnConectar.setText("Conectar");
				jBtnConectar.setBounds(0, 29, 305, 36);
				jBtnConectar.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent evt) {
						jBtnConectarMouseClicked(evt);
					}
				});
			}
			{
				jBtnMedir = new JButton();
				getContentPane().add(jBtnMedir);
				jBtnMedir.setText("Medir");
				jBtnMedir.setBounds(0, 572, 305, 36);
				jBtnMedir.setEnabled(false);
				jBtnMedir.addMouseListener(new MouseAdapter() {
					public void mouseClicked(MouseEvent evt) {
						jBtnMedirMouseClicked(evt);
					}
				});
			}
			pack();
			this.setSize(313, 701);
		} catch (Exception e) {
		    //add your error handling code here
			e.printStackTrace();
		}
	}
	
	private void jBtnMedirMouseClicked(MouseEvent evt) {
		//System.out.println("jBtnParar.mouseClicked, event="+evt);
		//TODO add your code for jBtnParar.mouseClicked
		
		int n = Integer.parseInt(jTxt.getText());
		
		// Define a velocidade padrao do robo
		jTxt.setText(String.valueOf((int)this.velocidadePadrao));
		jBtnVelocidadeMouseClicked(null);
		
		try {
			yAtual = 50;
			xAtual = 0;
			anguloAtual = 0;
			int i = 0;
			while(i < n) {
				
				dos.writeBytes("MED\n");
				//dos.writeInt(Integer.valueOf(jTxt.getText()));
				dos.flush();
				int distancia = dis.readInt() - 20; // TODO refatorar aqui
				System.out.println("I: " + (i + 1));
				System.out.println("yAtual: " + yAtual);
				System.out.println("xAtual: " + xAtual);
				System.out.println("anguloAtual: " + anguloAtual);
				System.out.println("Distancia: " + distancia);
				
				// Aqui a biblioteca fuzzy calcula qual o angulo a desviar
				int variacaoAngulo = (int) Math.round(Fuzzy.avalia(distancia, this.anguloAtual, this.yAtual));
				System.out.println("Variacao: " + variacaoAngulo);
				
				// Aqui eu atualizo o angulo previsto
				this.anguloAtual += variacaoAngulo;
				
				// Aqui eu atualizo a posi��o prevista
				this.xAtual += this.delta * Math.cos(anguloAtual * Math.PI / 180);
				this.yAtual += this.delta * Math.sin(anguloAtual * Math.PI / 180);
				
				
				// Aqui ele gira
				jTxt.setText(String.valueOf(variacaoAngulo));
				jBtnGirarEMouseClicked(null);
				dis.readInt();
				dis.readInt();
				
				// Aqui ele anda
				jTxt.setText(String.valueOf((int)this.delta));
				jBtnAndarMouseClicked(null);
				dis.readInt();
				dis.readInt();
				
				
				//jOut.setText(String.valueOf(distancia) + " - " + String.valueOf());
				i++;
			}	
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
		
		jTxt.setText(String.valueOf(n));
	}
	private void jBtnConectarMouseClicked(MouseEvent evt) {
		//System.out.println("jBtnConectar.mouseClicked, event="+evt);
		//TODO add your code for jBtnConectar.mouseClicked
		nxtComm = null;
		conectou = false;

		try {
			nxtComm = NXTCommFactory.createNXTComm(NXTCommFactory.BLUETOOTH);
		} catch (NXTCommException e) {
			System.out.println("Failed to load bluetooth driver");
			System.exit(1);
		}
		
		NXTInfo[] nxtInfo;
		nxtInfo = null;
		try {
			nxtInfo = nxtComm.search(null,NXTCommFactory.BLUETOOTH );
		} catch (NXTCommException e1) {
			// TODO Auto-generated catch block
			//e1.printStackTrace();
			System.out.println("Bluetooth devices not found!");
		}
		
		System.out.println("Connecting to " + nxtInfo[0].name);
		
		try {
			conectou = nxtComm.open(nxtInfo[0]); 
		} catch (NXTCommException e) {
                    
			System.out.println("Exception from open " + e.getMessage());
		}
		if (!conectou) {
			System.out.println("Failed to open " + nxtInfo[0].name);
		}
		else
		{
			jBtnVelocidade.setEnabled(true);
			jBtnAndar.setEnabled(true);
			jBtnVoltar.setEnabled(true);
			jBtnGirarE.setEnabled(true);
			jBtnGirarD.setEnabled(true);			
			jBtnVirarE.setEnabled(true);
			jBtnVirarD.setEnabled(true);
			jBtnParar.setEnabled(true);
			jBtnMedir.setEnabled(true);
			jBtnConectar.setEnabled(false);
			System.out.println("Connected to " + nxtInfo[0].name);
			
			//Criando streams de dados para o NXT
			is = nxtComm.getInputStream();
			os = nxtComm.getOutputStream();
			
			//Criando streams de dados gen�ricos
			dos = new DataOutputStream(os);
			dis = new DataInputStream(is);
		}
		
	}
	
	private void jBtnSairMouseClicked(MouseEvent evt) {
		//System.out.println("jBtnSair.mouseClicked, event="+evt);
		//TODO add your code for jBtnSair.mouseClicked
		if(conectou)
		{
			try {
				dos.writeBytes("END\n");		
				dos.flush();			
			} catch (IOException e) {
				// TODO Auto-generated catch block
				//e.printStackTrace();
			}
		}
		System.exit(0);
	}
	
	private void jBtnVelocidadeMouseClicked(MouseEvent evt) {
		//System.out.println("jBtnVelocidade.mouseClicked, event="+evt);
		//TODO add your code for jBtnVelocidade.mouseClicked
		
		try {
			dos.writeBytes("VEL\n");
			dos.writeInt(Integer.valueOf(jTxt.getText()));
			dos.flush();			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
		
	}
	
	private void jBtnAndarMouseClicked(MouseEvent evt) {
		//System.out.println("jBtnAndar.mouseClicked, event="+evt);
		//TODO add your code for jBtnAndar.mouseClicked
		try {
			dos.writeBytes("AND\n");
			dos.writeInt(Integer.valueOf(jTxt.getText()));
			dos.flush();			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
	}
	
	private void jBtnVoltarMouseClicked(MouseEvent evt) {
		//System.out.println("jBtnVoltar.mouseClicked, event="+evt);
		//TODO add your code for jBtnVoltar.mouseClicked
		
		try {
			dos.writeBytes("VOL\n");
			dos.writeInt(Integer.valueOf(jTxt.getText()));
			dos.flush();			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
	}
	
	private void jBtnGirarEMouseClicked(MouseEvent evt) {
		//System.out.println("jBtnGirarE.mouseClicked, event="+evt);
		//TODO add your code for jBtnGirarE.mouseClicked
		
		try {
			dos.writeBytes("GIR\n");
			dos.writeInt(Integer.valueOf(jTxt.getText()));
			dos.flush();			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
	}
	
	private void jBtnGirarDMouseClicked(MouseEvent evt) {
		//System.out.println("jBtnGirarD.mouseClicked, event="+evt);
		//TODO add your code for jBtnGirarD.mouseClicked
		
		try {
			dos.writeBytes("GIR\n");
			dos.writeInt((-1)*Integer.valueOf(jTxt.getText()));
			dos.flush();			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
	}
	
	private void jBtnVirarEMouseClicked(MouseEvent evt) {
		//System.out.println("jBtnVirarE.mouseClicked, event="+evt);
		//TODO add your code for jBtnVirarE.mouseClicked
		
		try {
			dos.writeBytes("ESQ\n");
			dos.writeInt(Integer.valueOf(jTxt.getText()));
			dos.flush();			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
	}
	
	private void jBtnVirarDMouseClicked(MouseEvent evt) {
		//System.out.println("jBtnVirarD.mouseClicked, event="+evt);
		//TODO add your code for jBtnVirarD.mouseClicked
		
		try {
			dos.writeBytes("DIR\n");
			dos.writeInt(Integer.valueOf(jTxt.getText()));
			dos.flush();			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
	}
	
	private void jBtnPararMouseClicked(MouseEvent evt) {
		//System.out.println("jBtnParar.mouseClicked, event="+evt);
		//TODO add your code for jBtnParar.mouseClicked
		
		try {
			dos.writeBytes("PAR\n");
			dos.writeInt(Integer.valueOf(jTxt.getText()));
			dos.flush();			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
	}

}
